package cn.tanghom.app.oa.service.impl;

import cn.tanghom.app.oa.mapper.LeaveMapper;
import cn.tanghom.app.oa.model.Leave;
import cn.tanghom.app.oa.service.LeaveService;
import cn.tanghom.support.db.DynamicDataSourceHolder;
import cn.tanghom.support.page.Pager;

import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.val;
import me.kafeitu.demo.activiti.util.DateConverter;

/**
 * 请假业务实现
 *
 * @author tanghom<tanghom@qq.com> on 2016/6/30
 */
@Service
public class LeaveServiceImpl implements LeaveService {
	static final String db_key = "oa";
	static final String ProcessDefinitionKey = "leave";
	
    @Resource
    private LeaveMapper leaveMapper;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    protected TaskService taskService;
    @Resource
    protected HistoryService historyService;
    @Resource
    protected RepositoryService repositoryService;
    @Resource
    private IdentityService identityService;
   
    
    @Override
    public void save(Leave leave) { 
    	try(val db = DynamicDataSourceHolder.active(db_key)){
    		leaveMapper.save(leave);
    	}
    }

    @Override
    public void update(Leave leave) {
    	try(val db = DynamicDataSourceHolder.active(db_key)){
    		leaveMapper.update(leave);
    	}
    }

    @Override
    public void delete(Long id) {
    	try(val db = DynamicDataSourceHolder.active(db_key)){
    		leaveMapper.delete(id);
    	}
    }

    @Override
    public Leave findById(Long id) {
    	try(DynamicDataSourceHolder.Active db = DynamicDataSourceHolder.active(db_key)){
    		return leaveMapper.findById(id);
    	}
    }

    @Override
    public Pager<Leave> findPageByParams(String userId, Integer status, Long index) {
    	try(DynamicDataSourceHolder.Active db = DynamicDataSourceHolder.active(db_key)){
	        Pager<Leave> pager = new Pager<Leave>();
	        pager.setIndex(index);
	        pager.setSize(10);
	        List<Leave> leaveList = leaveMapper.findPageByParams(userId, status, pager.startRow(), pager.getSize());
	        pager.setItems(leaveList);
	        Long totalRecord = leaveMapper.countByParams(userId, status);
	        pager.setTotalRecord(totalRecord);
	        return pager;
    	}
    }

    @Override
    public ProcessInstance startWorkflow(Leave entity, Map<String, Object> variables) {
    	try(val db = DynamicDataSourceHolder.active(db_key)){
    		leaveMapper.save(entity);
    	}
        String businessKey = entity.getId().toString();
        ProcessInstance processInstance = null;
        try {
            // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
            identityService.setAuthenticatedUserId(entity.getUser().getLoginName());
            processInstance = runtimeService.startProcessInstanceByKey(ProcessDefinitionKey, businessKey, variables);
            String processInstanceId = processInstance.getId();
            entity.setProcessInstanceId(processInstanceId);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        try(val db = DynamicDataSourceHolder.active(db_key)){
        	leaveMapper.update(entity);
        }
        return processInstance;
    }
    

	public List<Leave> getpagedepttask(String userid,int firstrow,int rowcount) {
		List<Leave> results=new ArrayList<Leave>();
		List<Task> tasks=taskService.createTaskQuery().taskCandidateGroup("deptLeader").listPage(firstrow, rowcount);
		for(Task task:tasks){
			String instanceid=task.getProcessInstanceId();
			ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
			String businesskey=ins.getBusinessKey();
			Leave a = leaveMapper.findById(new Long(businesskey));
			a.setTask(task);
			results.add(a);
		}
		return results;
	}
	
	public int getalldepttask(String userid) {
		List<Task> tasks=taskService.createTaskQuery().taskCandidateGroup("deptLeader").list();
		return tasks.size();
	}

	public Leave getleave(int id) {
		Leave leave=leaveMapper.findById(new Long(id));
		return leave;
	}

	public List<Leave> getpagehrtask(String userid,int firstrow,int rowcount) {
		List<Leave> results=new ArrayList<Leave>();
		List<Task> tasks=taskService.createTaskQuery().taskCandidateGroup("hr").listPage(firstrow, rowcount);
		for(Task task:tasks){
			String instanceid=task.getProcessInstanceId();
			ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
			String businesskey=ins.getBusinessKey();
			Leave a= getleave(Integer.parseInt(businesskey));
			a.setTask(task);
			results.add(a);
		}
		return results;
	}

	public int getallhrtask(String userid) {
		List<Task> tasks=taskService.createTaskQuery().taskCandidateGroup("hr").list();
		return tasks.size();
	}
	
	public List<Leave> getpageXJtask(String userid,int firstrow,int rowcount) {
		List<Leave> results=new ArrayList<Leave>();
		List<Task> tasks=taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("销假").listPage(firstrow, rowcount);
		for(Task task:tasks){
			String instanceid=task.getProcessInstanceId();
			ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
			String businesskey=ins.getBusinessKey();
			Leave a = getleave(Integer.parseInt(businesskey));
			a.setTask(task);
			results.add(a);
		}
		return results;
	}

	public int getallXJtask(String userid) {
		List<Task> tasks=taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("销假").list();
		return tasks.size();
	}
	
	public List<Leave> getpageupdateapplytask(String userid,int firstrow,int rowcount) {
		List<Leave> results=new ArrayList<Leave>();
		List<Task> tasks=taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("调整申请").listPage(firstrow, rowcount);
		for(Task task:tasks){
			String instanceid=task.getProcessInstanceId();
			ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
			String businesskey=ins.getBusinessKey();
			Leave a= getleave(Integer.parseInt(businesskey));
			a.setTask(task);
			results.add(a);
		}
		return results;
	}
	
	public int getallupdateapplytask(String userid) {
		List<Task> tasks=taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("调整申请").list();
		return tasks.size();
	}
	
	public  void completereportback(String taskid, String realstart_time, String realend_time) {		
		Task task=taskService.createTaskQuery().taskId(taskid).singleResult();
		String instanceid=task.getProcessInstanceId();
		ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
		String businesskey=ins.getBusinessKey();
		Leave a= getleave(Integer.parseInt(businesskey));
		
		try {
			a.setRealityStartTime(DateConverter.doConvertToDate(realstart_time));
			a.setRealityEndTime(DateConverter.doConvertToDate(realend_time));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		leaveMapper.update(a);
		taskService.complete(taskid);
	}

	public void updatecomplete(String taskid, Leave leave,String reapply) {
		Task task=taskService.createTaskQuery().taskId(taskid).singleResult();
		String instanceid=task.getProcessInstanceId();
		ProcessInstance ins=runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
		String businesskey=ins.getBusinessKey();
		Leave a = getleave(Integer.parseInt(businesskey));
		a.setLeaveType(leave.getLeaveType());
		a.setStartTime(leave.getStartTime());
		a.setEndTime(leave.getEndTime());
		a.setReason(leave.getReason());
		Map<String,Object> variables=new HashMap<String,Object>();
		variables.put("reapply", reapply);
		if(reapply.equals("true")){
			leaveMapper.update(a);
			taskService.complete(taskid,variables);
		}else
			taskService.complete(taskid,variables);
	}
	
	public List<String> getHighLightedFlows(  
	        ProcessDefinitionEntity processDefinitionEntity,  
	        List<HistoricActivityInstance> historicActivityInstances) {  
	  
	    List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId  
	    /**
	    for (int i = 0; i < historicActivityInstances.size(); i++) {// 对历史流程节点进行遍历  
	        ActivityImpl activityImpl = processDefinitionEntity 
	                .findActivity(historicActivityInstances.get(i)  
	                        .getActivityId());// 得 到节点定义的详细信息  
	        List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点  
	        if ((i + 1) >= historicActivityInstances.size()) {  
	            break;  
	        }  
	        ActivityImpl sameActivityImpl1 = processDefinitionEntity.
	                .findActivity(historicActivityInstances.get(i + 1)  
	                        .getActivityId());// 将后面第一个节点放在时间相同节点的集合里  
	        sameStartTimeNodes.add(sameActivityImpl1);  
	        for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {  
	            HistoricActivityInstance activityImpl1 = historicActivityInstances  
	                    .get(j);// 后续第一个节点  
	            HistoricActivityInstance activityImpl2 = historicActivityInstances  
	                    .get(j + 1);// 后续第二个节点  
	            if (activityImpl1.getStartTime().equals(  
	                    activityImpl2.getStartTime())) {// 如果第一个节点和第二个节点开始时间相同保存  
	                ActivityImpl sameActivityImpl2 = processDefinitionEntity  
	                        .findActivity(activityImpl2.getActivityId());  
	                sameStartTimeNodes.add(sameActivityImpl2);  
	            } else {// 有不相同跳出循环  
	                break;  
	            }  
	        }  
	        List<PvmTransition> pvmTransitions = activityImpl  
	                .getOutgoingTransitions();// 取出节点的所有出去的线  
	        for (PvmTransition pvmTransition : pvmTransitions) {// 对所有的线进行遍历  
	            ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition  
	                    .getDestination();// 如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示  
	            if (sameStartTimeNodes.contains(pvmActivityImpl)) {  
	                highFlows.add(pvmTransition.getId());  
	            }  
	        }  
	    }  
	    */
	    return highFlows;  
	}  
}
